// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_render_step_view_culling.h"
#include "mk_scene.h"
#include "mk_camera.h"
#include "mk_culling_processor.h"
#include "mk_render_frame.h"
#include "mk_error.h"

namespace MK3DE
{
	const char* CRenderStepViewCulling::RenderStepName = "__RenderStepViewCulling";

	CRenderStepViewCulling::CRenderStepViewCulling(CRenderFrame* renderFrame)
		: CRenderStep(renderFrame, CRenderStepViewCulling::RenderStepName)
	{
		_camera = NULL;
		_scene = NULL;
		_cullingProcessor = NULL;

	}

	CRenderStepViewCulling::~CRenderStepViewCulling()
	{
		SAFE_RELEASE(_scene);
		SAFE_RELEASE(_camera);
		SAFE_RELEASE(_cullingProcessor);
	}

	void CRenderStepViewCulling::SetCamera(CCamera* camera)
	{
		_camera = camera;
		camera->AddRef();
	}

	void CRenderStepViewCulling::SetScene(CScene* scene)
	{
		_scene = scene;
		scene->AddRef();
	}

	void CRenderStepViewCulling::SetCullingProcessor(CCullingProcessor* cullingProcessor)
	{
		SAFE_RELEASE(_cullingProcessor);
		_cullingProcessor = cullingProcessor;
		cullingProcessor->AddRef();
	}

	void CRenderStepViewCulling::Render()
	{
		if (!_cullingProcessor || !_camera || !_scene)
			return;

		// Cull entity.
		_visibleEntity.Clear();
		_cullingProcessor->Culling(_scene, _camera, _visibleEntity);

		__CalculateWaterHeight();
	}

	void CRenderStepViewCulling::__CalculateWaterHeight()
	{
		if (_visibleEntity.vecEntity[ERT_WATER].size() == 0)
			return;

		float height = 0;
		std::vector<CEntity*>::iterator i = _visibleEntity.vecEntity[ERT_WATER].begin();
		while (i != _visibleEntity.vecEntity[ERT_WATER].end())
		{
			CEntity* entity = *i;
			CSceneNode* sceneNode = entity->GetAttachedSceneNode();
			height += sceneNode->GetAbsoluteTransformation()._42;
			++i;
		}

		height /= (float)_visibleEntity.vecEntity[ERT_WATER].size();
		_visibleWaterHeight = height;
	}
}